import { _decorator, Component, Node } from 'cc';
import { Unit } from '../Unit';
import { EconomicCom } from './EconomicCom';
import { Global, LootType, UnitType } from '../../Util/Global';
import GameEventMgr, { GameEvent } from '../../Model/GameEventMgr';
import { UICtrl } from '../../Ctrl/UICtrl';
import { GameStickerType } from '../../Model/GameStickerMgr';
const { ccclass, property } = _decorator;

export interface IDestruction {
    /**获取目标造成的破坏值 */
    GetDestructionValue: (() => number);
}

/**
 * 可破环组件 记录破坏进度
 */
@ccclass('DestructableCom')
export class DestructableCom extends Component {

    unit: Unit = null;
    destroyer: IDestruction[] = [];
    maxShield: number = 0;
    shield: number = 0;
    shield_cost_electric: number = 0;
    shield_recover_max_speed: number = 10;//护盾每秒最大恢复速度

    private _remain_hp: number = 1;

    //护盾受伤恢复冷却时间
    private _shieldDamageTickTime: number = 0;
    get unitEconomicCom() {
        return this._unitEconomicCom;
    }
    set unitEconomicCom(value: EconomicCom) {

        if (value) {
            this._remain_hp = value.electric_power_remain;
        }
        this._unitEconomicCom = value;
    }
    private _unitEconomicCom: EconomicCom = null;

    get next_remain_hp() {
        return this._remain_hp;
    }

    protected update(dt: number): void {
        if (!this.unit || Global.gameManager.pause) return;

        if (this._shieldDamageTickTime > 0) {
            this._shieldDamageTickTime -= dt;

            if (this.shield_cost_electric > 0 && this._unitEconomicCom) {
                this._unitEconomicCom.AddPowerOutExtraFrame(this.shield_cost_electric);
            }
        }
        else {
            let recover_speed = this.maxShield - this.shield;
            recover_speed = Math.min(recover_speed, this.shield_recover_max_speed);
            if (this.shield_cost_electric > 0 && this._unitEconomicCom) {
                this._unitEconomicCom.AddPowerOutExtraFrame(this.shield_cost_electric);
                if (this._unitEconomicCom.electric_power_remain > 0) {
                    this.shield += dt * recover_speed;
                }
                else {
                    this.shield -= dt * this.shield;
                }
            }
            else {
                this.shield += dt * recover_speed;
            }
            this.shield = Math.min(this.shield, this.maxShield);
        }
    }

    protected lateUpdate(dt: number): void {
        if (Global.gameManager.pause) return;

        this._remain_hp = this.CalculateDisruptingProgress();

        if (this.unit && !this.unit.death_flag) {
            if (this.unit.unitType <= UnitType.UnitSpacecra && this.unit.hp <= 0) {
                console.log('该单位应该被销毁，但是没有被及时处理！', this.unit.uuid);
                this.unit.DestroySelf('该单位应该被销毁，但是没有被及时处理！');
            }
        }
        if (this._remain_hp <= 0 && this.unit.unitType > UnitType.UnitSpacecra && this._unitEconomicCom == null) {
            this.unitEconomicCom = this.unit.getComponent(EconomicCom);
        }
    }

    protected onEnable(): void {

        this.unit = this.getComponent(Unit);
        this.unit.destructable = this;
        this.unit.hp = this.unit.start_hp;
    }

    protected onDisable(): void {
        this.destroyer = [];
        if (this.unit.unitType <= UnitType.UnitSpacecra && this.unit.start_hp <= 0) {
            console.log('警告==>初始生命值为0！！！');
        }
        this._remain_hp = this.unit.start_hp;
        this.shield = 0;
        this.maxShield = 0;
        this._unitEconomicCom = null;
        this.shield_cost_electric = 0;
        this.shield_recover_max_speed = 10;
    }

    AddLateDestruction(source: IDestruction) {
        this.destroyer.push(source);

        this._remain_hp = this.CalculateDisruptingProgress();
    }

    /**等待真正命中造成伤害 */
    RemoveLateDestruction(source: IDestruction) {
        let index = this.destroyer.indexOf(source);
        if (index !== -1) {
            this.destroyer.splice(index, 1);
        }
        this._remain_hp = this.CalculateDisruptingProgress();
    }

    /**汇总破坏进度(还未被破坏) */
    CalculateDisruptingProgress() {

        let hp = this._unitEconomicCom && this._unitEconomicCom.isValid ?
            this._unitEconomicCom.electric_power_remain : this.unit.hp;
        let sum = hp + this.shield;
        for (let i = 0; i < this.destroyer.length; i++) {
            sum -= this.destroyer[i].GetDestructionValue();
        }
        return sum;
    }

    /**真正命中造成伤害 */
    OnDamage(source: IDestruction) {
        this.RemoveLateDestruction(source);

        this.OnDamageByValue(source.GetDestructionValue());
    }

    OnDamageByValue(value: number) {
        if (!this.unit) return;

        this._shieldDamageTickTime = 3;//受伤护盾恢复冷却时间
        this.unitEconomicCom = this.unit.getComponent(EconomicCom);
        if (this.shield > 0) {
            this._shieldDamageTickTime = 0;//没有击破不用冷却
            this.shield -= value;
            this.shield = Math.max(0, this.shield);

            if (this.unit.isInScreenPos) {
                Global.gameManager.mapCtrl.mapSpawner.
                    SpawnUnitImmediatelyLoot(LootType.Shield, this.unit.unitWorldPos, 1);
            }
        }
        else if (this.unit.unitType <= UnitType.UnitSpacecra) {

            this.unit.hp -= value;
            if (this.unit.hp <= 0) {
                this.unit.DestroySelf('被击毁！');
            }
        }
        else if (this._unitEconomicCom) {
            let subtract = value;
            this._unitEconomicCom.damageTickTime = 1;
            this._unitEconomicCom.electric_power_remain -= subtract;

            if (this.unit.isInScreenPos) {
                Global.gameManager.mapCtrl.mapSpawner.
                    SpawnUnitImmediatelyLoot(LootType.Electric, this.unit.unitWorldPos, 1);
            }

            if (this.unit.playerCtrl) {
                GameEventMgr.Dispatch(GameEvent.ECViewDataChangeToTip, 'elec', -subtract);
            }

            if (this._unitEconomicCom.electric_power_remain <= 0) {
                GameEventMgr.Dispatch(GameEvent.EconomicComBroken, this.unit);
            }
        }

        this._remain_hp = this.CalculateDisruptingProgress();

        if (!this.unit.playerCtrl && this.unit.isInScreenPos && this._unitEconomicCom) {
            UICtrl.CreateStickerRenderer(this.unit, GameStickerType.PlanetEconomicSticker);
        }
    }
}


